package com.ywyself.ext.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 时间日期处理
 * 
 * @author ywyself
 * @createdate 2017-08-30 16:43:00
 */
public class YsDateUtils {

	/**
	 * 将日期转换为指定格式的字符串 <br>
	 * <table>
	 * <tr>
	 * <th>格式</th>
	 * <th>输出</th>
	 * </tr>
	 * <tr>
	 * <td>yyyy-MM-dd HH:mm:ss</td>
	 * <td>2017-08-12 13:08:25</td>
	 * </tr>
	 * </table>
	 * <hr>
	 * 示例时间：2017-08-12 13:15:23<br/>
	 * yyyy/yyy/y:2017;yy:17;MM:08;M:8;HH:24小时制;hh:12小时制
	 * <hr>
	 * 
	 * @param date
	 *            日期
	 * @param dateFormat
	 *            格式
	 * @return
	 */
	public static String toStr(Date date, String dateFormat) {
		SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
		return formatter.format(date);

	}

	/**
	 * 将日期转换为指定格式的字符串
	 * 
	 * @param date
	 *            日期
	 * @return 字符：yyyy-MM-dd HH:mm:ss
	 */
	public static String toStr(Date date) {
		return YsDateUtils.toStr(date, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 将时间戳转换为时间格式的字符串
	 * 
	 * @param timestamp
	 *            10位的时间戳
	 * @param dateFormat
	 *            时间格式
	 * @return 时间字符串
	 */
	public static String toStr(long timestamp, String dateFormat) {
		Date date = new Date(new Long(timestamp + "000"));
		return YsDateUtils.toStr(date, dateFormat);

	}

	/**
	 * 将时间戳转换为时间格式的字符串
	 * 
	 * @param timestamp
	 *            10位的时间戳
	 * @return 时间字符串，格式yyyy-MM-dd HH:mm:ss
	 */
	public static String toStr(long timestamp) {
		return YsDateUtils.toStr(timestamp, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 将时间格式的字符串转换为日期对象
	 * 
	 * @param dateStr
	 *            时间格式的字符串
	 * @param dateFormat
	 *            时间格式 如：yyyy-MM-dd HH:mm:ss
	 * @return 日期对象
	 */
	public static Date toDate(String dateStr, String dateFormat) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
			Date date = sdf.parse(dateStr);
			return date;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将时间格式的字符串转换为日期对象
	 * 
	 * @param dateStr
	 *            时间格式的字符串，如：yyyy-MM-dd HH:mm:ss
	 * @return 日期对象
	 */
	public static Date toDate(String dateStr) {
		return toDate(dateStr, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 将时间戳转换为日期类型
	 * 
	 * @param timestamp
	 *            10位的时间戳
	 * @return
	 */
	public static Date toDate(long timestamp) {
		return new Date(new Long(timestamp + "000"));
	}

	/**
	 * 将时间格式的字符串转换为时间戳
	 * 
	 * @param dateStr
	 *            时间字符串
	 * @param dateFormat
	 *            时间格式
	 * @return 时间戳，10位的时间戳
	 */
	public static long toLong(String dateStr, String dateFormat) {
		return YsDateUtils.toDate(dateStr, dateFormat).getTime() / 1000;
	}

	/**
	 * 将时间格式的字符串转换为时间戳
	 * 
	 * @param dateStr
	 *            时间格式的字符串，格式为yyyy-MM-dd HH:mm:ss
	 * @return 时间戳，10位的时间戳
	 */
	public static long toLong(String dateStr) {
		return YsDateUtils.toLong(dateStr, "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 日期对象转换为long类型的数据
	 * 
	 * @param date
	 *            日期
	 * @return 时间戳，10位的时间戳
	 */
	public static long toLong(Date date) {
		return date.getTime() / 1000;
	}

	/**
	 * 以数组的形式返回日期中的年月日时分秒
	 * 
	 * @param date
	 *            日期
	 * @return 数组：[yyyy,MM,dd,HH,mm,ss]
	 */
	public static String[] toArray(Date date) {
		String datetime = YsDateUtils.toStr(date, "yyyy-MM-dd-HH-mm-ss");
		return datetime.split("-");
	}

	/**
	 * 获取当前时间
	 * 
	 * @param dateFormat
	 *            时间格式，如：yyyy-MM-dd
	 * 
	 * @return 当前时间字符串
	 */
	public static String getStr(String dateFormat) {
		return YsDateUtils.toStr(new Date(), dateFormat);
	}

	/**
	 * 获取当前日期+时间
	 * 
	 * @return 字符串：yyyy-MM-dd HH:mm:ss
	 */
	public static String getStr() {
		return YsDateUtils.getStr("yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 获取当前的时间戳
	 * 
	 * @return 时间戳，10位的时间戳
	 */
	public static long getLong() {
		return new Date().getTime() / 1000;
	}

	/**
	 * 传入的时间与现在相比，过去了多少秒
	 * 
	 * @param date
	 *            传入的时间
	 * @return <font size=+1>>0</font>：传入的时间点已经过去,<font size=+1>过去的时间点</font>
	 *         <br/>
	 *         <font size=+1>=0</font>：传入的时间点为当前时间,<font size=+1>就是现在</font>
	 *         <br/>
	 *         <font size=+1><0</font>：传入的时间点还没有过去,<font size=+1>未来的时间点</font>
	 *         <br/>
	 *         结果的绝对值为两个时间点相差的秒数
	 */
	public static long compareTo(Date date) {
		return YsDateUtils.getLong() - YsDateUtils.toLong(date);
	}

	/**
	 * 传入的时间与现在相比，过去了多少秒
	 * 
	 * @param date
	 *            传入的时间
	 * @return <font size=+1>>0</font>：传入的时间点已经过去,<font size=+1>过去的时间点</font>
	 *         <br/>
	 *         <font size=+1>=0</font>：传入的时间点为当前时间,<font size=+1>就是现在</font>
	 *         <br/>
	 *         <font size=+1><0</font>：传入的时间点还没有过去,<font size=+1>未来的时间点</font>
	 *         <br/>
	 *         结果的绝对值为两个时间点相差的秒数
	 */
	public static long compareTo(String dateStr) {
		return YsDateUtils.getLong() - YsDateUtils.toLong(dateStr);
	}

	/**
	 * 比较两个时间点
	 * 
	 * @param dateA
	 * @param dateB
	 * @return >0 时间A在时间B之后<br/>
	 *         =0 时间A与时间B为同一个时间<br/>
	 *         <0 时间A在时间B之前
	 */
	public static long compare(Date dateA, Date dateB) {
		return YsDateUtils.toLong(dateA) - YsDateUtils.toLong(dateB);
	}

	/**
	 * 这个时间点是否过去了
	 * 
	 * @param date
	 *            日期对象
	 * @return true|过去了
	 */
	public static boolean isPast(Date date) {
		return (YsDateUtils.getLong() - YsDateUtils.toLong(date)) > 0;
	}

	/**
	 * 这个时间点是否过去了
	 * 
	 * @param dateStr
	 *            时间格式字符串yyyy-MM-dd-HH-mm-ss
	 * @return true|过去了
	 */
	public static boolean isPast(String dateStr) {
		return (YsDateUtils.getLong() - YsDateUtils.toLong(dateStr)) > 0;
	}

	/**
	 * 以数组的形式返回当前时间的年月日时分秒
	 * 
	 * @return 数组：[yyyy,MM,dd,HH,mm,ss]
	 */
	public static String[] getArray() {
		return YsDateUtils.toArray(new Date());
	}

	/**
	 * 获取本周第n天的日期
	 * 
	 * @param n
	 *            本周第几天，范围应该是[1,7]
	 * @param isSundayFirst
	 *            星期天为没周第一天
	 * @return 日期字符串yyyy-MM-dd
	 */
	public static String getCurrentWeekDay(int n, boolean isSundayFirst) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = new GregorianCalendar();
		if (isSundayFirst) {
			calendar.setFirstDayOfWeek(Calendar.SUNDAY);
		} else {
			calendar.setFirstDayOfWeek(Calendar.MONDAY);
		}
		calendar.setTime(new Date());
		int index = n - 1;
		if (index < 0) {
			throw new ArrayIndexOutOfBoundsException("数值太小，范围应该是[1,7]");
		} else if (index > 7) {
			throw new ArrayIndexOutOfBoundsException("数值太大，范围应该是[1,7]");
		}
		calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() + index);
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取本周第n天的日期，星期天为每周的第一天
	 * 
	 * @param n
	 *            本周第几天，范围应该是[1,7]
	 * @return 日期字符串yyyy-MM-dd
	 */
	public static String getCurrentWeekDay(int n) {
		return YsDateUtils.getCurrentWeekDay(n, true);
	}

	/**
	 * 获取本月的第几天的日期
	 * 
	 * @param n
	 *            第几天
	 * @return 日期字符串yyyy-MM-dd
	 */
	public static String getCurrentMonthDay(int n) {
		Calendar calendar = Calendar.getInstance();
		int index = n;
		if (index < 1) {
			throw new ArrayIndexOutOfBoundsException(
					"数值太小，范围应该是[1," + calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		} else if (index > calendar.getActualMaximum(Calendar.DAY_OF_MONTH)) {
			throw new ArrayIndexOutOfBoundsException(
					"数值太大，范围应该是[1," + calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		}
		calendar.set(Calendar.DAY_OF_MONTH, index);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取本月第一天的日期
	 * 
	 * @return 日期字符串yyyy-MM-dd
	 */
	public static String getCurrentMonthFirstDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取本月最后一天的日期
	 * 
	 * @return 日期字符串yyyy-MM-dd
	 */
	public static String getCurrentMonthLastDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(calendar.getTime());
	}

	private static String getDay(int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DATE, n);
		return toStr(calendar.getTime(), "yyyy-MM-dd");
	}

	/**
	 * 将日期往前推几天的日期,如果n=0则为今天
	 * 
	 * @param n
	 *            几天前
	 * @return 日期字符串yyyy-MM-dd
	 */
	public static String getDayBefore(int n) {
		return YsDateUtils.getDay(-n);
	}

	/**
	 * 将日期往后推几天的日期,如果n=0则为今天
	 * 
	 * @param n
	 *            几天后
	 * @return 日期字符串yyyy-MM-dd
	 */
	public static String getDayAfter(int n) {
		return YsDateUtils.getDay(+n);
	}

	/**
	 * 将x小时转换为m天n小时
	 * 
	 * @param hours
	 *            小时
	 * @return
	 */
	public static String hourToFriendView(int hours) {
		if (hours > 24) {
			int d = hours / 24;
			int h = hours % 24;
			if (h > 0) {
				return d + "天" + h + "小时";
			} else {
				return d + "天";
			}
		} else {
			return hours + "小时";
		}
	}
}
